﻿//-------------------------------------------------------------------------------
// <copyright file="IWorkspace.cs" company="bbv Software Services AG">
//   Copyright (c) 2009 bbv Software Services AG
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.Data;

namespace bbv.DomainDrivenDesign.Interfaces
{
    /// <summary>
    ///   Defines an interface to implement a Unit of Work workspace 
    ///   based on the Unit of Work pattern of Martin Fowler.
    /// </summary>
    public interface IWorkspace : IDisposable
    {
        /// <summary>
        ///   Gets the underlying database connection of the workspace.
        /// </summary>
        /// <value>
        ///   The database connection as a
        ///   <see cref="T:System.Data.IDbConnection" />
        ///   .
        /// </value>
        IDbConnection Connection { get; }
        /// <summary>
        ///   Persists all pending updates to the data source.
        /// </summary>
        /// <exception cref="OptimisticOfflineLockException" />
        void SubmitChanges();
        /// <summary>
        ///   Accepts all changes made to objects in the
        ///   <see cref="IWorkspace" />
        ///   context.
        /// </summary>
        void AcceptAllChanges();
        ///<summary></summary>
        ///<param name="id"></param>
        ///<typeparam name="TEntity"></typeparam>
        ///<typeparam name="TId"></typeparam>
        ///<returns></returns>
        TEntity GetById<TEntity, TId>(TId id) where TEntity : class;
        /// <summary>
        ///   Returns the persistent instance of the given named entity with the given identifier,
        ///   or null if there is no such persistent instance. (If the instance, or a proxy for the
        ///   instance, is already associated with the session, return that instance or proxy.)
        /// </summary>
        /// <typeparam name="TEntity">
        ///   The type of the entity.
        /// </typeparam>
        /// <param name="entityWithKey">
        ///   An entity with a key.
        /// </param>
        /// <returns>
        ///   A persistent instance or null.
        /// </returns>
        TEntity Get<TEntity>(TEntity entityWithKey) where TEntity : class;
        /// <summary>
        ///   Inserts an entity in a pending insert state to the
        ///   <see cref="IWorkspace" />
        ///   context.
        /// </summary>
        /// <typeparam name="TEntity">
        ///   The type of the entity.
        /// </typeparam>
        /// <param name="entity">
        ///   A transient instance of a persistent class.
        /// </param>
        void Add<TEntity>(TEntity entity) where TEntity : class;
        ///<summary></summary>
        ///<param name="entity"></param>
        ///<typeparam name="TEntity"></typeparam>
        ///<returns></returns>
        TEntity Create<TEntity>(TEntity entity) where TEntity : class;
        /// <summary>
        ///   Remove an entity from this table into a pending delete state.
        /// </summary>
        /// <typeparam name="TEntity">
        ///   The type of the entity.
        /// </typeparam>
        /// <param name="entity">
        ///   The instance to be removed.
        /// </param>
        void Delete<TEntity>(TEntity entity) where TEntity : class;
        /// <summary>
        ///   Update the persistent instance with the identifier of the given transient instance.
        /// </summary>
        /// <typeparam name="TEntity">
        ///   The type of the entity.
        /// </typeparam>
        /// <param name="entity">
        ///   The detached object that has property updates
        ///   to apply to the original object.
        /// </param>
        /// <remarks>
        ///   If there is a persistent instance with the same identifier, an exception is thrown. If
        ///   the given transient instance has a
        ///   <see langword="null" />
        ///   identifier, an exception will be thrown.
        /// </remarks>
        void Update<TEntity>(TEntity entity) where TEntity : class;
        /// <summary>
        ///   Cleans all cached objects within the
        ///   <see cref="IWorkspace" />
        ///   .
        /// </summary>
        void Clean();
        /// <summary>
        ///   Updates an object in the object context with data from the persisted store.
        ///   Overrides all the current values with the values from the database.
        /// </summary>
        /// <typeparam name="TEntity">
        ///   The type of the entity.
        /// </typeparam>
        /// <param name="entity">
        ///   The entity to be refreshed.
        /// </param>
        void Refresh<TEntity>(TEntity entity) where TEntity : class;
        /// <summary>
        ///   Attach an object or object graph to the object context if the object
        ///   has an entity key.
        /// </summary>
        /// <remarks>
        ///   Changed properties of an attached entity are ignored and will not be saved to the database.
        /// </remarks>
        /// <typeparam name="TEntity">
        ///   The type of the entity.
        /// </typeparam>
        /// <param name="entityWithKey">
        ///   The entity to attach.
        /// </param>
        void Attach<TEntity>(TEntity entityWithKey) where TEntity : class;
        /// <summary>
        ///   Removes the specified object from the
        ///   <see cref="IWorkspace" />
        ///   context.
        /// </summary>
        /// <remarks>
        ///   The entity will only be removed from the tracking manager and not removed from the id map.
        /// </remarks>
        /// <typeparam name="TEntity">
        ///   The type of the entity.
        /// </typeparam>
        /// <param name="entity">
        ///   The entity to detach from the context.
        /// </param>
        void Detach<TEntity>(TEntity entity) where TEntity : class;
        /// <summary>
        ///   Creates an
        ///   <see cref="T:bbv.DomainDrivenDesign.Interfaces.IQueryableContext`1" />
        ///   in the current object context
        /// </summary>
        /// <typeparam name="TEntity">
        ///   The type of the
        ///   <see cref="T:bbv.DomainDrivenDesign.Interfaces.IQueryableContext`1" />
        ///   .
        /// </typeparam>
        /// <returns>
        ///   An
        ///   <see cref="T:bbv.DomainDrivenDesign.Interfaces.IQueryableContext`1" />
        ///   of the specified type.
        /// </returns>
        IQueryableContext<TEntity> CreateQuery<TEntity>() where TEntity : class;
    }
}